
package org.test

import grails.test.mixin.*

import org.junit.*
import org.tests.IdealPriceStrategy;
import org.tests.MainIdealPriceStrategy

@TestFor(PriceService)
@Mock([Product, PriceAssessment])
class PriceServiceTests {

	void testEmptyPrices(){
		Product product = new Product(barcode: 'Test1', description: 'A test Product')
		product.save(flush: true, validate: false)
		
		assert Product.count() == 1
		
		PriceService service = new PriceService();
		
		assert service.getLowestPrice(product) == 0
		assert service.getHighestPrice(product) == 0
		assert service.getAveragePrice(product) == 0
		assert service.getIdealPrice(product) == 0
		assert service.getNumberOfPrices(product) == 0
	}
	
    void testLowestPrice() {
    	Product product = new Product(barcode: 'Test1', description: 'A test Product')
		product.save(flush: true, validate: false)
		
		assert Product.count() == 1
		
		PriceAssessment price1 = new PriceAssessment(price: 1, product: product)
		price1.save(flush: true, validate: false)

		PriceAssessment price2 = new PriceAssessment(price: 10, product: product)
		price2.save(flush: true, validate: false)
		
		product.prices = [price1, price2]
		
		PriceService service = new PriceService();
		
		assert service.getLowestPrice(product) == 1
    }
	
	void testHighestPrice() {
		Product product = new Product(barcode: 'Test1', description: 'A test Product')
		product.save(flush: true, validate: false)
		
		assert Product.count() == 1
		
		PriceAssessment price1 = new PriceAssessment(price: 1, product: product)
		price1.save(flush: true, validate: false)

		PriceAssessment price2 = new PriceAssessment(price: 10, product: product)
		price2.save(flush: true, validate: false)
		
		product.prices = [price1, price2]
		
		PriceService service = new PriceService();
		
		assert service.getHighestPrice(product) == 10
	}
	
	void testAveragePrice() {
		Product product = new Product(barcode: 'Test1', description: 'A test Product')
		product.save(flush: true, validate: false)
		
		assert Product.count() == 1
		
		PriceAssessment price1 = new PriceAssessment(price: 1, product: product)
		price1.save(flush: true, validate: false)

		PriceAssessment price2 = new PriceAssessment(price: 10, product: product)
		price2.save(flush: true, validate: false)
		
		product.prices = [price1, price2]
		
		PriceService service = new PriceService();
		
		assert service.getAveragePrice(product) == 5.5
	}
	
	void testCountPrices() {
		Product product = new Product(barcode: 'Test1', description: 'A test Product')
		product.save(flush: true, validate: false)
		
		assert Product.count() == 1
		
		PriceAssessment price1 = new PriceAssessment(price: 1, product: product)
		price1.save(flush: true, validate: false)

		PriceAssessment price2 = new PriceAssessment(price: 10, product: product)
		price2.save(flush: true, validate: false)
		
		product.prices = [price1, price2]
		
		PriceService service = new PriceService();
		
		assert service.getNumberOfPrices(product) == 2
	}
	
	void testIdealPriceStrategy() {
		Product product = new Product(barcode: 'Test1', description: 'A test Product')
		product.save(flush: true, validate: false)
		
		assert Product.count() == 1
		
		PriceAssessment price1 = new PriceAssessment(price: 1, product: product)
		price1.save(flush: true, validate: false)

		PriceAssessment price2 = new PriceAssessment(price: 10, product: product)
		price2.save(flush: true, validate: false)
		
		product.prices = [price1, price2]
		
		PriceService service = new PriceService();
		service.idealPriceStrategy = new MainIdealPriceStrategy();
		
		assert service.getIdealPrice(product) == 6.6
	}
}
